﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace ThermometerBar
{
    public delegate void OnProgressChangedHandler(object sender, EventArgs e);
   
    /// <summary>
    /// 自定义实现进度条控件
    /// </summary>
    public partial class Bar : Control
    {
        protected  OnProgressChangedHandler PC;
        public event OnProgressChangedHandler ProgressChanged
        {
            add 
            {
                if (PC != null)
                {
                }
            }
            remove { }
        }
        
        #region 私有字段

        private int _BarWidth = 100;
        private int _BarHeight = 10;   //控件本身的宽度、高度值
        private EBarDirection _BarDirection=EBarDirection.Horizontal;   //控件显示方向（默认水平）

        private float _MaxValue = 0.0F;
        private float _MinValue = 0.0F;//最大值，最小值
        private float _Length = 0F;
        private float _Step = 1F;
        private float _Percent = 0.0F; //数据长度，步长值，完成百分比
        
        bool _ShowText = true;  //是否显示进度值

        #endregion

       /// <summary>
       /// 构造函数
       /// </summary>
        public Bar()
        {
            InitializeComponent();

            this._MaxValue = this._BarWidth;
            this._Length = this._MaxValue - this._MinValue;

            if (this.Width <= this.BarWidth)
                this.KeepMinWidth();
            if (this.Height <= this.BarHeight)
                this.KeepMinHeight();

            this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.ResizeRedraw | ControlStyles.UserPaint, true);
        }

        /// <summary>
        /// 重写Control类中的OnPaint方法，绘制控件
        /// </summary>
        /// <param name="pe"></param>
        protected override void OnPaint(PaintEventArgs pe)
        {
            //绘制进度条边框
            Pen pen = new Pen(Color.Blue);//创建蓝色画笔

            //绘制进度条控件
            if (this.BarDirection == EBarDirection.Horizontal)
                pe.Graphics.DrawRectangle(pen, 5, 5, BarWidth, BarHeight); 
            else
                pe.Graphics.DrawRectangle(pen, 5, 5, BarHeight, BarWidth);


            //绘制进度条
            pe.Graphics.FillRectangle(Brushes.Green, new RectangleF(7, 7, _Percent * (this.BarWidth-3), BarHeight - 3));

            //绘制进度条文字
            if (_ShowText)
            {
                string per = (_Percent*100) + "%";
                pe.Graphics.DrawString(per, new Font("", 7f), Brushes.Black, new PointF(this.BarWidth / 2 - 3, this.BarHeight / 2 - 1));
            }

        }

        #region 公共属性

        /// <summary>
        /// 进度条的宽度
        /// </summary>
        [Browsable(true), Category("Appearence"), Description("进度条宽度"),DefaultValue(100)]
        public int BarWidth
        {
            get { return _BarWidth; }
            set
            {
                if (_BarWidth != value)
                {
                    this._BarWidth = value;
                    KeepMinWidth();
                    this.Invalidate();
                }
            }
        }

        /// <summary>
        /// 进度条的高度
        /// </summary>
        [Browsable(true), Category("Appearence"), Description("进度条高度"),DefaultValue(10)]
        public int BarHeight
        {
            get { return _BarHeight; }
            set
            {
                if (_BarHeight != value)
                {
                    this._BarHeight = value;
                    KeepMinHeight();
                    this.Invalidate();
                }
            }
        }
       
        /// <summary>
        /// 进度条的方向
        /// </summary>
        [Browsable(true), Category("Appearence"), Description("进度条方向"),DefaultValue(EBarDirection.Horizontal)]
        public EBarDirection BarDirection
        {
            get { return _BarDirection; }
            set 
            {
                if (this._BarDirection != value)
                {
                    this._BarDirection = value;
                    swapWidthAndHeight();
                    this.Invalidate();
                }
            }
        }

        /// <summary>
        /// 显示进度数值
        /// </summary>
        [Browsable(true),Category("Appearence"),Description("是否显示百分比数值"),DefaultValue(true)]
        public bool ShowBarPercent
        {
            get { return this._ShowText; }
            set
            {
                if (this._ShowText != value)
                {
                    this._ShowText = value;
                    this.Invalidate();
                }
            }
        }

        /// <summary>
        /// 进度条长度
        /// </summary>
        [Browsable(true),Category("Appearence"),Description("进度条长度"),DefaultValue(100F)]
        public float Length
        {
            get { return this._Length; }
            set { this._Length = value; }
        }

        /// <summary>
        /// 进度步长值
        /// </summary>
        [Browsable(true),Category("Appearence"),Description("进度步长值"),DefaultValue(0.1F)]
        public float Step
        {
            get { return this._Step; }
            set { this._Step = value; }
        }

        /// <summary>
        /// 完成度百分比
        /// </summary>
        public float Percent
        {
            get { return this._Percent; }
            set { this._Percent = value; }
        }

        #endregion

        #region 私有方法
        
        /// <summary>
        /// 交换控件的宽高属性值
        /// </summary>
        private void swapWidthAndHeight()
        {
            int temp = this.Width;
            this.Width = this.Height;
            this.Height = temp;

        }
        /// <summary>
        /// 控件的最小宽度值
        /// </summary>
        private void KeepMinWidth()
        {
            this.Width = this.BarWidth + 10;
        }
        /// <summary>
        /// 控件的最小高度值
        /// </summary>
        private void KeepMinHeight()
        {
            this.Height = this.BarHeight + 10;
        }

        #endregion

        /// <summary>
        /// 更新完成度（注意最大值，及最小值区间；如果有负数，那么Complete取值？）
        /// </summary>
        /// <param name="completed"></param>
        public void UpdateProgressPercent(float percent)
        {
            this.Percent = percent;
            this.Invalidate();
        }
        /// <summary>
        /// 更新完成值，非百分比
        /// </summary>
        /// <param name="complete"></param>
        public void UpdateProgressComplete(float complete)
        {
            float _p = complete / this.Length;
            this.UpdateProgressPercent(_p);
        }

    }
    /// <summary>
    /// 方向枚举
    /// </summary>
    public enum EBarDirection
    {
        /// <summary>
        /// 垂直方向
        /// </summary>
        Verification,
        /// <summary>
        /// 水平方向
        /// </summary>
        Horizontal
    }
}
